<?php
namespace payment\unionPay;
use app\mainadmin\model\PaymentModel;
use app\publics\model\UpdatePayModel;
use think\facade\Log;

class unionPay
{
    function __construct() {
        $model = new PaymentModel();
        $pay_config = $model->where('pay_code','weixin')->value('pay_config');
        $pay_config = json_decode(urldecode($pay_config),true);
        $this->appid = $pay_config['unionpay_appid'];
        $this->appkey = $pay_config['unionpay_key'];
        $this->mid = $pay_config['unionpay_mid'];
        $this->tid = $pay_config['unionpay_tid'];
        $this->sysno = $pay_config['unionpay_sysno'];
    }

    public function unifiedOrder($data)
    {
        $data = [
            "msgId"=>time(),
            "requestTimestamp"=>date("Y-m-d H:i:s",time()),
            "merOrderId"=> $data['order_sn'],
            "srcReserve"=>"webpay",
            "mid"=> $this->mid,
            "tid"=> $this->tid,
            "instMid"=>"YUEDANDEFAULT",
            "attachedData"=>"unionPay",
            "totalAmount"=>$data['order_amount']*100,
            "tradeType"=>"JSAPI",
            "subOpenId" => $data['openid'],
            "notifyUrl" => SITE_URL.'/index.php/publics/Payment/notifyUrl/pay_code/'.$data['pay_code'].'/type/unionPay',
            "returnUrl" => SITE_URL.'/pages/shop/order/info?order_id='.$data['order_id']
        ];

        $body=json_encode($data);
        $url = 'https://api-mop.chinaums.com/v1/netpay/wx/unified-order';
        $res = $this->curlpost($url,$body);
        return json_decode($res,true);
    }
    public function webUnifiedOrder($data)
    {
        $postdata = [
            "msgId"=>time(),
            "requestTimestamp"=>date("Y-m-d H:i:s",time()),
            "merOrderId"=> $data['order_sn'],
            "srcReserve"=>"webpay",
            "mid"=> $this->mid,
            "tid"=> $this->tid,
            "instMid"=>"H5DEFAULT",
            "attachedData"=>"unionPay",
            "totalAmount"=>$data['order_amount']*100,
            "notifyUrl" => SITE_URL.'/index.php/publics/Payment/notifyUrl/pay_code/'.$data['pay_code'].'/type/unionPay',
            "returnUrl" => SITE_URL.'/pages/shop/order/info?order_id='.$data['order_id']
        ];
        dump($postdata);
        $body=json_encode($postdata);
        $url = 'https://api-mop.chinaums.com/v1/netpay/wxpay/h5-pay';
        $res = $this->curlpost($url,$body);
        dump($res);
        return json_decode($res,true);
    }
    public function mpUnifiedOrder($data)
    {
        $data = [
            "msgId"=>time(),
            "requestTimestamp"=>date("Y-m-d H:i:s",time()),
            "merOrderId"=> $data['order_sn'],
            "srcReserve"=>"webpay",
            "mid"=> $this->mid,
            "tid"=> $this->tid,
            "instMid"=>"MINIDEFAULT",
            "attachedData"=>"unionPay",
            "totalAmount"=>$data['order_amount']*100,
            "tradeType"=>"JSAPI",
            "subOpenId" => $data['openid'],
            "notifyUrl" => SITE_URL.'/index.php/publics/Payment/notifyUrl/pay_code/'.$data['pay_code'].'/type/unionPay',
            "returnUrl" => SITE_URL.'/pages/shop/order/info?order_id='.$data['order_id']
        ];

        $body=json_encode($data);
        $url = 'https://api-mop.chinaums.com/v1/netpay/wx/unified-order';
        $res = $this->curlpost($url,$body);
        return json_decode($res,true);
    }
    public function refundOrder($data)
    {
        $data = [
            "msgId"=>time(),
            "requestTimestamp"=>date("Y-m-d H:i:s",time()),
            "merOrderId"=> $data['transaction_id'],
            "srcReserve"=>"webpay",
            "mid"=> $this->mid,
            "tid"=> $this->tid,
            "instMid"=>"YUEDANDEFAULT",
            "refundAmount"=>$data['refund_amount']*100
        ];

        $body=json_encode($data);
        $url = 'https://api-mop.chinaums.com/v1/netpay/refund';
        $res = $this->curlpost($url,$body);
        return json_decode($res,true);
    }

    public function webRefundOrder($data)
    {
        $data = [
            "msgId"=>time(),
            "requestTimestamp"=>date("Y-m-d H:i:s",time()),
            "merOrderId"=> $data['transaction_id'],
            "srcReserve"=>"webpay",
            "mid"=> $this->mid,
            "tid"=> $this->tid,
            "instMid"=>"H5DEFAULT",
            "refundAmount"=>$data['refund_amount']*100
        ];

        $body=json_encode($data);
        $url = 'https://api-mop.chinaums.com/v1/netpay/refund';
        $res = $this->curlpost($url,$body);
        return json_decode($res,true);
    }

    public function mpRefundOrder($data)
    {
        $data = [
            "msgId"=>time(),
            "requestTimestamp"=>date("Y-m-d H:i:s",time()),
            "merOrderId"=> $data['transaction_id'],
            "srcReserve"=>"webpay",
            "mid"=> $this->mid,
            "tid"=> $this->tid,
            "instMid"=>"MINIDEFAULT",
            "refundAmount"=>$data['refund_amount']*100
        ];

        $body=json_encode($data);
        $url = 'https://api-mop.chinaums.com/v1/netpay/refund';
        $res = $this->curlpost($url,$body);
        return json_decode($res,true);
    }
    public function getSignature($timestamp,$nonce,$body){
        $str = bin2hex(hash('sha256', $body, true));
//        dump('签名内容：'.$body);
//        dump('SHA256(签名内容)：'.$str);
//        dump('appId+ Timestamp + Nonce + SHA256(签名内容)：'."$this->appid$timestamp$nonce$str");
//        dump('HmacSHA256(appId+ Timestamp + Nonce + SHA256(签名内容),appKey)：'.bin2hex(hash_hmac('sha256', "$this->appid$timestamp$nonce$str", $this->appkey, true)));
        $signature = base64_encode(hash_hmac('sha256', "$this->appid$timestamp$nonce$str", $this->appkey, true));
//        dump('signature：'.$signature);
        return $signature;
    }

    function response()
    {
        $data = input('post.');
        if ($data['status'] != 'TRADE_SUCCESS'){
            Log::debug("unionPay Response:" . json_encode($data));
            return false;
        }
        if (!array_key_exists("merOrderId", $data)) {
            $msg = "输入参数不正确";
            //Log::DEBUG("call back:" . $msg);
            return false;
        }
        $data['transaction_id'] = $data['merOrderId'];
        $data['merOrderId'] = str_replace($this->sysno,'',$data['merOrderId']);
        $data['total_fee'] = $data['totalAmount'];
        $data['order_sn']= $data['merOrderId']; //商户系统的订单号，与请求一致。
        $data['pay_code'] = 'weixin';//支付宝交易号
        $res = (new UpdatePayModel())->update($data);
        return $res ? 'SUCCESS' : '';
    }

    public function refund($data){
        if(!empty($data["transaction_id"])){
            $res = $this->refundOrder($data);
            if ($res['errCode'] == 'NO_ORDER'){
                $res = $this->webRefundOrder($data);
                if ($res['errCode'] == 'NO_ORDER'){
                    $res = $this->mpRefundOrder($data);
                }
            }
            if ($res['errCode'] != 'SUCCESS'){
                return $res['errMsg'];
            }
            if($res['status'] != 'TRADE_SUCCESS'){
                return $res['errMsg'];
            }
            return true;
        }else{
            return false;
        }
    }

    public function curlpost($url,$body){
        $timestamp = date("YmdHis",time());
        $nonce = md5(uniqid(microtime(true),true));
        $signature = $this->getSignature($timestamp,$nonce,$body);
        $authorization = "OPEN-BODY-SIG AppId=\"$this->appid\", Timestamp=\"$timestamp\", Nonce=\"$nonce\", Signature=\"$signature\"";
        $ch = curl_init();//初始化curl

        curl_setopt($ch, CURLOPT_URL, $url);//抓取指定网页
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Content-Length: ' . strlen($body),
            'Authorization: '.$authorization
        ));
        $output = curl_exec($ch);//运行curl
        curl_close($ch);
        return $output;

    }
}
